﻿using Acme.BookStore.FormWhx.Ruku;
using Acme.BookStore.FormWhx.Storehouse;
using Acme.BookStore.FormWhx.Binlocation;
using Acme.BookStore.FormWhxDto.RukuDto;
using Acme.BookStore.FormWhxDto.StorehouseDto;
using Acme.BookStore.FormWhxDto.BinlocationDto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace Acme.BookStore.FormWhxDto.Ruku
{
    public class RuKuService : CrudAppService<
        RuKuModel, RuKuModelDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateRuKuDto>, IRuKuService
    {
        private readonly IRepository<RuKuDetailModel, Guid> _rukuDetailRepository;
        private readonly IRepository<SorehouseModels, Guid> _storehouseRepository;
        private readonly IRepository<ConnectFromModel, Guid> _connectFromRepository;

        public RuKuService(
            IRepository<RuKuModel, Guid> rukuRepository,
            IRepository<RuKuDetailModel, Guid> rukuDetailRepository,
            IRepository<SorehouseModels, Guid> storehouseRepository,
            IRepository<ConnectFromModel, Guid> connectFromRepository
        ) : base(rukuRepository)
        {
            _rukuDetailRepository = rukuDetailRepository;
            _storehouseRepository = storehouseRepository;
            _connectFromRepository = connectFromRepository;
        }

        // 主表+明细表添加
        public async Task AddRuKuWithDetailsAsync(CreateRuKuWithDetailsDto input)
        {
            var ruku = ObjectMapper.Map<CreateUpdateRuKuDto, RuKuModel>(input.Ruku);
            ruku = await Repository.InsertAsync(ruku, autoSave: true);
            foreach (var detailDto in input.RukuDetails)
            {
                var detail = ObjectMapper.Map<CreateUpdateRuKuDetailsDto, RuKuDetailModel>(detailDto);
                detail.RukuId = ruku.Id;
                await _rukuDetailRepository.InsertAsync(detail, autoSave: true);
            }
        }

        // 主表+明细表编辑
        public async Task UpdateRuKuWithDetailsAsync(CreateRuKuWithDetailsDto input)
        {
            if (input.Id == null || input.Id == Guid.Empty)
                throw new ArgumentException("Id不能为空");
            var ruku = await Repository.GetAsync(input.Id.Value);
            ObjectMapper.Map(input.Ruku, ruku);
            await Repository.UpdateAsync(ruku);
            var dbDetails = await _rukuDetailRepository.GetListAsync(x => x.RukuId == input.Id.Value);
            var inputIds = input.RukuDetails.Where(d => d.Id != Guid.Empty).Select(d => d.Id).ToList();
            // 删除
            var toDelete = dbDetails.Where(d => !inputIds.Contains(d.Id)).ToList();
            foreach (var del in toDelete)
                await _rukuDetailRepository.DeleteAsync(del);
            // 更新和新增
            foreach (var detailDto in input.RukuDetails)
            {
                if (detailDto.Id != Guid.Empty)
                {
                    var dbDetail = dbDetails.First(x => x.Id == detailDto.Id);
                    ObjectMapper.Map(detailDto, dbDetail);
                    await _rukuDetailRepository.UpdateAsync(dbDetail);
                }
                else
                {
                    var newDetail = ObjectMapper.Map<CreateUpdateRuKuDetailsDto, RuKuDetailModel>(detailDto);
                    newDetail.RukuId = ruku.Id;
                    await _rukuDetailRepository.InsertAsync(newDetail);
                }
            }
        }

        // 主表+明细表删除
        public async Task DeleteRuKuWithDetailsAsync(Guid id)
        {
            var details = await _rukuDetailRepository.GetListAsync(x => x.RukuId == id);
            foreach (var d in details)
                await _rukuDetailRepository.DeleteAsync(d);
            await Repository.DeleteAsync(id);
        }

        // 获取所有类型枚举
        public async Task<ListResultDto<IRuKuService.RuTypeDto>> GetTypeAsync()
        {
            var list = Enum.GetValues(typeof(RuType)).Cast<RuType>()
                .Select(x => new IRuKuService.RuTypeDto { Id = (int)x, Name = x.ToString() }).ToList();
            return new ListResultDto<IRuKuService.RuTypeDto>(list);
        }

        // 获取所有库位  枚举
        public async Task<ListResultDto<IRuKuService.StatusDto>> GetStatusDtoAsync()
        {
            var list = Enum.GetValues(typeof(RuStatus)).Cast<RuStatus>()
                .Select(x => new IRuKuService.StatusDto { Id = (int)x, Name = x.ToString() }).ToList();
            return new ListResultDto<IRuKuService.StatusDto>(list);
        }

        // 获取仓库名称  下拉
        public async Task<ListResultDto<StorehouseDto.StorehouseDto>> GetStorehouseDtoAsync()
        {
            var list = await _storehouseRepository.GetListAsync();
            var result = ObjectMapper.Map<List<SorehouseModels>, List<StorehouseDto.StorehouseDto>>(list);
            return new ListResultDto<StorehouseDto.StorehouseDto>(result);
        }

        // 获取关联单号  下拉
        public async Task<ListResultDto<ConnectFromModelDto>> ConnectFromModelDtoAsync()
        {
            var list = await _connectFromRepository.GetListAsync();
            var result = ObjectMapper.Map<List<ConnectFromModel>, List<ConnectFromModelDto>>(list);
            return new ListResultDto<ConnectFromModelDto>(result);
        }

        // 根据条件查询
        public async Task<PagedResultDto<RuKuQueryDto>> GetListByConditionRuKuQueryAsync(RuKuQueryDto input)
        {
            var query = await Repository.GetQueryableAsync();
            if (!string.IsNullOrWhiteSpace(input.RuKuNo))
                query = query.Where(x => x.RuKuNo.Contains(input.RuKuNo));
            if (input.RuKuType.HasValue)
                query = query.Where(x => x.RuKuType == input.RuKuType.Value);
            if (input.RuKuStatus.HasValue)
                query = query.Where(x => x.RuKuStatus == input.RuKuStatus.Value);
            if (input.StorehouseName != 0)
                query = query.Where(x => x.StorehouseName == input.StorehouseName);
            var totalCount = query.Count();
            var items = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            var result = ObjectMapper.Map<List<RuKuModel>, List<RuKuQueryDto>>(items);
            return new PagedResultDto<RuKuQueryDto>(totalCount, result);
        }
    }
}
